package com.ruoyi.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.BusinessConstant;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.bo.SyncUserBo;
import com.ruoyi.common.core.domain.vo.UserInfoVo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.UserCommonService;
import com.ruoyi.common.core.service.UserEventCommonService;
import com.ruoyi.common.enums.UserBusinessSubType;
import com.ruoyi.common.enums.UserBusinessType;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.user.domain.UserInfo;
import com.ruoyi.user.domain.bo.UserFileUpdateBo;
import com.ruoyi.user.domain.bo.UserInfoBo;
import com.ruoyi.user.domain.vo.DrugUserVo;
import com.ruoyi.user.mapper.UserInfoMapper;
import com.ruoyi.user.service.IUserInfoService;
import com.ruoyi.common.core.domain.bo.CustomQueryBo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * 人员信息Service业务层处理
 *
 * @author strongme
 * @date 2023-04-24
 */
@RequiredArgsConstructor
@Service
public class UserInfoServiceImpl implements IUserInfoService, UserCommonService<UserInfoBo> {

    private final UserInfoMapper baseMapper;
    private final ISysUserService userService;
    private final UserEventCommonService userEventCommonService;

    /**
     * 查询人员信息
     */
    @Override
    @Cacheable(value = CacheNames.USER_DRUG, key = "#id")
    public UserInfoVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public List<UserInfoVo> queryByIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Lists.newArrayList();
        }
        return baseMapper.selectVoBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserInfo(UserInfoVo userInfoVo) {
        UserInfoBo update = BeanUtil.toBean(userInfoVo, UserInfoBo.class);
        return updateByBo(update);
    }

    /**
     * 查询人员信息列表
     */
    @Override
    public TableDataInfo<UserInfoVo> queryPageList(UserInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<UserInfo> lqw = buildQueryWrapper(bo);
        Page<UserInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (bo.isRenderJfrq()) {
            userEventCommonService.renderUserJf(result.getRecords());
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询人员信息列表
     */
    @Override
    public List<UserInfoVo> queryList(UserInfoBo bo) {
        LambdaQueryWrapper<UserInfo> lqw = buildQueryWrapper(bo);
        List<UserInfoVo> result = baseMapper.selectVoList(lqw);
        if (bo.isRenderJfrq()) {
            userEventCommonService.renderUserJf(result);
        }
        return result;
    }

    private LambdaQueryWrapper<UserInfo> buildQueryWrapper(UserInfoBo bo) {
        LambdaQueryWrapper<UserInfo> lqw = Wrappers.lambdaQuery();
        if (bo.getSubType() != null && CollUtil.isNotEmpty(bo.getSubType().getDrugTypeList())) {
            lqw.in(UserInfo::getType, bo.getSubType().getDrugTypeList());
        }
        if (bo.getSubTypeList() != null && CollUtil.isNotEmpty(bo.getSubTypeList())) {
            List<String> types = Lists.newArrayList();
            bo.getSubTypeList().forEach(subType -> {
                types.addAll(subType.getDrugTypeList());
            });
            lqw.in(UserInfo::getType, types);
        }
        lqw.eq(StringUtils.isNotBlank(bo.getAvatar()), UserInfo::getAvatar, bo.getAvatar());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), UserInfo::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getArea()), UserInfo::getArea, bo.getArea());
        lqw.like(StringUtils.isNotBlank(bo.getName()), UserInfo::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getGender()), UserInfo::getGender, bo.getGender());
        lqw.eq(StringUtils.isNotBlank(bo.getMz()), UserInfo::getMz, bo.getMz());
        lqw.eq(StringUtils.isNotBlank(bo.getZzmm()), UserInfo::getZzmm, bo.getZzmm());
        lqw.eq(bo.getHeight() != null, UserInfo::getHeight, bo.getHeight());
        lqw.eq(StringUtils.isNotBlank(bo.getIdno()), UserInfo::getIdno, bo.getIdno());
        lqw.eq(bo.getBirthday() != null, UserInfo::getBirthday, bo.getBirthday());
        lqw.eq(StringUtils.isNotBlank(bo.getWhcd()), UserInfo::getWhcd, bo.getWhcd());
        lqw.eq(StringUtils.isNotBlank(bo.getJdjg()), UserInfo::getJdjg, bo.getJdjg());
        lqw.eq(bo.getJdsj() != null, UserInfo::getJdsj, bo.getJdsj());
        lqw.eq(bo.getFzr() != null, UserInfo::getFzr, bo.getFzr());
        lqw.eq(StringUtils.isNotBlank(bo.getHjdpcs()), UserInfo::getHjdpcs, bo.getHjdpcs());
        lqw.eq(StringUtils.isNotBlank(bo.getHjd()), UserInfo::getHjd, bo.getHjd());
        lqw.eq(StringUtils.isNotBlank(bo.getHjdxz()), UserInfo::getHjdxz, bo.getHjdxz());
        lqw.eq(StringUtils.isNotBlank(bo.getJzdpcs()), UserInfo::getJzdpcs, bo.getJzdpcs());
        lqw.eq(StringUtils.isNotBlank(bo.getJzd()), UserInfo::getJzd, bo.getJzd());
        lqw.eq(StringUtils.isNotBlank(bo.getJzdxz()), UserInfo::getJzdxz, bo.getJzdxz());
        lqw.eq(StringUtils.isNotBlank(bo.getJyqk()), UserInfo::getJyqk, bo.getJyqk());
        lqw.eq(StringUtils.isNotBlank(bo.getGddh()), UserInfo::getGddh, bo.getGddh());
        lqw.eq(StringUtils.isNotBlank(bo.getMobile()), UserInfo::getMobile, bo.getMobile());
        lqw.eq(StringUtils.isNotBlank(bo.getHyzk()), UserInfo::getHyzk, bo.getHyzk());
        lqw.eq(StringUtils.isNotBlank(bo.getMqzt()), UserInfo::getMqzt, bo.getMqzt());
        lqw.eq(StringUtils.isNotBlank(bo.getSfyfmzj()), UserInfo::getSfyfmzj, bo.getSfyfmzj());
        lqw.eq(StringUtils.isNotBlank(bo.getFlwsbh()), UserInfo::getFlwsbh, bo.getFlwsbh());
        lqw.eq(StringUtils.isNotBlank(bo.getYsdabh()), UserInfo::getYsdabh, bo.getYsdabh());
        lqw.eq(StringUtils.isNotBlank(bo.getSsjwq()), UserInfo::getSsjwq, bo.getSsjwq());
        lqw.eq(StringUtils.isNotBlank(bo.getLydplx()), UserInfo::getLydplx, bo.getLydplx());
        lqw.eq(StringUtils.isNotBlank(bo.getJntc()), UserInfo::getJntc, bo.getJntc());
        lqw.eq(StringUtils.isNotBlank(bo.getJds()), UserInfo::getJds, bo.getJds());
        lqw.eq(StringUtils.isNotBlank(bo.getFxdj()), UserInfo::getFxdj, bo.getFxdj());
        lqw.eq(bo.getRsrq() != null, UserInfo::getRsrq, bo.getRsrq());
        lqw.eq(bo.getCsrq() != null, UserInfo::getCsrq, bo.getCsrq());
        lqw.eq(bo.getKfjzzx() != null, UserInfo::getKfjzzx, bo.getKfjzzx());
        lqw.eq(StringUtils.isNotBlank(bo.getSzry()), UserInfo::getSzry, bo.getSzry());
        lqw.eq(StringUtils.isNotBlank(bo.getSzdw()), UserInfo::getSzdw, bo.getSzdw());
        lqw.eq(bo.getJdqxqrq() != null, UserInfo::getJdqxqrq, bo.getJdqxqrq());
        lqw.eq(bo.getBdrq() != null, UserInfo::getBdrq, bo.getBdrq());
        lqw.eq(StringUtils.isNotBlank(bo.getQtfzjl()), UserInfo::getQtfzjl, bo.getQtfzjl());
        lqw.eq(StringUtils.isNotBlank(bo.getZwbh()), UserInfo::getZwbh, bo.getZwbh());
        lqw.eq(StringUtils.isNotBlank(bo.getDnabh()), UserInfo::getDnabh, bo.getDnabh());
        lqw.eq(StringUtils.isNotBlank(bo.getHelpPlan()), UserInfo::getHelpPlan, bo.getHelpPlan());
        lqw.eq(StringUtils.isNotBlank(bo.getTermType()), UserInfo::getTermType, bo.getTermType());
        lqw.eq(StringUtils.isNotBlank(bo.getZxdq()), UserInfo::getZxdq, bo.getZxdq());
        lqw.eq(StringUtils.isNotBlank(bo.getZxdwxc()), UserInfo::getZxdwxc, bo.getZxdwxc());
        lqw.eq(StringUtils.isNotBlank(bo.getZldwxc()), UserInfo::getZldwxc, bo.getZldwxc());
        lqw.eq(StringUtils.isNotBlank(bo.getGrcrjb()), UserInfo::getGrcrjb, bo.getGrcrjb());
        lqw.eq(bo.getQjcsrq() != null, UserInfo::getQjcsrq, bo.getQjcsrq());
        lqw.eq(StringUtils.isNotBlank(bo.getJssqkfqszdqzglcs()), UserInfo::getJssqkfqszdqzglcs, bo.getJssqkfqszdqzglcs());
        lqw.eq(StringUtils.isNotBlank(bo.getCjywwczlmz()), UserInfo::getCjywwczlmz, bo.getCjywwczlmz());
        lqw.eq(StringUtils.isNotBlank(bo.getSfjrkfcs()), UserInfo::getSfjrkfcs, bo.getSfjrkfcs());
        lqw.eq(StringUtils.isNotBlank(bo.getSqjdkfxys()), UserInfo::getSqjdkfxys, bo.getSqjdkfxys());
        lqw.eq(StringUtils.isNotBlank(bo.getSqjdkfzrs()), UserInfo::getSqjdkfzrs, bo.getSqjdkfzrs());
        lqw.eq(StringUtils.isNotBlank(bo.getYsrqk()), UserInfo::getYsrqk, bo.getYsrqk());
        lqw.eq(StringUtils.isNotBlank(bo.getStzk()), UserInfo::getStzk, bo.getStzk());
        lqw.eq(StringUtils.isNotBlank(bo.getWffzqk()), UserInfo::getWffzqk, bo.getWffzqk());
        lqw.eq(StringUtils.isNotBlank(bo.getDqzk()), UserInfo::getDqzk, bo.getDqzk());
        lqw.eq(StringUtils.isNotBlank(bo.getJszsfdx()), UserInfo::getJszsfdx, bo.getJszsfdx());
        lqw.eq(bo.getJwxdrs() != null, UserInfo::getJwxdrs, bo.getJwxdrs());
        lqw.eq(StringUtils.isNotBlank(bo.getClxx()), UserInfo::getClxx, bo.getClxx());
        lqw.eq(StringUtils.isNotBlank(bo.getShbzqk()), UserInfo::getShbzqk, bo.getShbzqk());
        lqw.eq(StringUtils.isNotBlank(bo.getJybzqk()), UserInfo::getJybzqk, bo.getJybzqk());
        lqw.eq(StringUtils.isNotBlank(bo.getJtqk()), UserInfo::getJtqk, bo.getJtqk());
        lqw.eq(StringUtils.isNotBlank(bo.getStzkfj()), UserInfo::getStzkfj, bo.getStzkfj());
        lqw.eq(bo.getCcxdsj() != null, UserInfo::getCcxdsj, bo.getCcxdsj());
        lqw.eq(bo.getCcxdbchsj() != null, UserInfo::getCcxdbchsj, bo.getCcxdbchsj());
        lqw.eq(StringUtils.isNotBlank(bo.getQkqk()), UserInfo::getQkqk, bo.getQkqk());
        lqw.eq(bo.getZhycxdbjljdkssj() != null, UserInfo::getZhycxdbjljdkssj, bo.getZhycxdbjljdkssj());
        lqw.eq(bo.getZhycxdbjljdjssj() != null, UserInfo::getZhycxdbjljdjssj, bo.getZhycxdbjljdjssj());
        lqw.eq(StringUtils.isNotBlank(bo.getSfytrzyqxd()), UserInfo::getSfytrzyqxd, bo.getSfytrzyqxd());
        lqw.eq(bo.getLjjdcs() != null, UserInfo::getLjjdcs, bo.getLjjdcs());
        lqw.eq(StringUtils.isNotBlank(bo.getLjjdsj()), UserInfo::getLjjdsj, bo.getLjjdsj());
        lqw.eq(StringUtils.isNotBlank(bo.getZjxdcs()), UserInfo::getZjxdcs, bo.getZjxdcs());
        lqw.eq(StringUtils.isNotBlank(bo.getXdhdzwgjdzs()), UserInfo::getXdhdzwgjdzs, bo.getXdhdzwgjdzs());
        lqw.eq(StringUtils.isNotBlank(bo.getXdhdzwgjdjt()), UserInfo::getXdhdzwgjdjt, bo.getXdhdzwgjdjt());
        lqw.eq(StringUtils.isNotBlank(bo.getXdhdzwgjdsh()), UserInfo::getXdhdzwgjdsh, bo.getXdhdzwgjdsh());
        lqw.eq(StringUtils.isNotBlank(bo.getXdfs()), UserInfo::getXdfs, bo.getXdfs());
        lqw.eq(StringUtils.isNotBlank(bo.getDply()), UserInfo::getDply, bo.getDply());
        lqw.eq(StringUtils.isNotBlank(bo.getXdcs()), UserInfo::getXdcs, bo.getXdcs());
        lqw.eq(StringUtils.isNotBlank(bo.getXdfw()), UserInfo::getXdfw, bo.getXdfw());
        lqw.eq(StringUtils.isNotBlank(bo.getCcxdyy()), UserInfo::getCcxdyy, bo.getCcxdyy());
        lqw.eq(StringUtils.isNotBlank(bo.getXdzjly()), UserInfo::getXdzjly, bo.getXdzjly());
        lqw.eq(StringUtils.isNotBlank(bo.getJdhcsfmqxyy()), UserInfo::getJdhcsfmqxyy, bo.getJdhcsfmqxyy());
        lqw.eq(StringUtils.isNotBlank(bo.getFxdpyyxlys()), UserInfo::getFxdpyyxlys, bo.getFxdpyyxlys());
        lqw.eq(StringUtils.isNotBlank(bo.getFxdpyystys()), UserInfo::getFxdpyystys, bo.getFxdpyystys());
        lqw.eq(StringUtils.isNotBlank(bo.getFxdpyyshhjys()), UserInfo::getFxdpyyshhjys, bo.getFxdpyyshhjys());
        lqw.eq(StringUtils.isNotBlank(bo.getTbr()), UserInfo::getTbr, bo.getTbr());
        lqw.eq(bo.getTbsj() != null, UserInfo::getTbsj, bo.getTbsj());
        lqw.eq(StringUtils.isNotBlank(bo.getTbdw()), UserInfo::getTbdw, bo.getTbdw());
        lqw.eq(StringUtils.isNotBlank(bo.getShenheren()), UserInfo::getShenheren, bo.getShenheren());
        lqw.eq(bo.getShsj() != null, UserInfo::getShsj, bo.getShsj());
        lqw.eq(StringUtils.isNotBlank(bo.getShdw()), UserInfo::getShdw, bo.getShdw());
        lqw.eq(StringUtils.isNotBlank(bo.getLxdh()), UserInfo::getLxdh, bo.getLxdh());
        lqw.eq(bo.getSqjdsqkfryqzsj() != null, UserInfo::getSqjdsqkfryqzsj, bo.getSqjdsqkfryqzsj());
        lqw.eq(bo.getSqjdsqkfgzxzcyqzsj() != null, UserInfo::getSqjdsqkfgzxzcyqzsj, bo.getSqjdsqkfgzxzcyqzsj());
        lqw.eq(bo.getSqjdsqkfgzzfzrqzsj() != null, UserInfo::getSqjdsqkfgzzfzrqzsj, bo.getSqjdsqkfgzzfzrqzsj());
        lqw.eq(bo.getZxsj() != null, UserInfo::getZxsj, bo.getZxsj());
        lqw.eq(StringUtils.isNotBlank(bo.getWfxwbg()), UserInfo::getWfxwbg, bo.getWfxwbg());
        lqw.eq(StringUtils.isNotBlank(bo.getQmjcws()), UserInfo::getQmjcws, bo.getQmjcws());
        return lqw;
    }

    /**
     * 新增人员信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(UserInfoBo bo) {
        UserInfo add = BeanUtil.toBean(bo, UserInfo.class);
        validEntityBeforeSave(add);
        if (bo.getFzr() == null) {
            add.setFzr(LoginHelper.getUserId());
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        SyncUserBo syncUserBo = extractUserBo(bo);
        userService.syncUser(syncUserBo);
        return flag;
    }

    /**
     * 修改人员信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CacheNames.USER_DRUG, key = "#bo.id", condition = "#bo.id != null")
    public Boolean updateByBo(UserInfoBo bo) {
        UserInfo update = BeanUtil.toBean(bo, UserInfo.class);
        validEntityBeforeSave(update);
        SyncUserBo syncUserBo = extractUserBo(bo);
        userService.syncUser(syncUserBo);
        int r = baseMapper.updateById(update);
        CacheUtils.evict(CacheNames.USER_DRUG, bo.getId());
        return r > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(UserInfo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除人员信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        ids.forEach(id -> {
            CacheUtils.evict(CacheNames.USER_DRUG, id);
            userEventCommonService.clearUserEventInfo(id);
        });
        userService.deleteUserByBusinessIds(ids);
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CacheNames.USER_DRUG, key = "#bo.userId", condition = "#bo.userId != null")
    public Boolean updateFile(UserFileUpdateBo bo) {
        Long userId = bo.getUserId();
        UserInfo userInfo = baseMapper.selectById(userId);
        userInfo.setAvatar(bo.getAvatar());
        userInfo.setJds(bo.getJds());
        userInfo.setSqjdkfxys(bo.getSqjdkfxys());
        userInfo.setSqjdkfzrs(bo.getSqjdkfzrs());
        userInfo.setZzws(bo.getZzws());
        baseMapper.updateById(userInfo);
        return Boolean.TRUE;
    }

    @Override
    public SyncUserBo extractUserBo(UserInfoBo bo) {
        SyncUserBo syncUserBo = BeanUtil.toBean(bo, SyncUserBo.class);
        syncUserBo.setMobile(bo.getMobile());
        syncUserBo.setUserType(UserType.SYS_USER.getUserType());
        syncUserBo.setBusinessType(UserBusinessType.USER_DRUG);
        syncUserBo.setBusinessSubType(UserBusinessSubType.getUserType(bo.getType(), UserBusinessType.USER_DRUG));
        syncUserBo.setBusinessId(bo.getId());
        return syncUserBo;
    }

    @Override
    public List<UserInfoVo> customQueryList(CustomQueryBo param) {
        QueryWrapper<UserInfo> qw = this.buildCustomQuery(param);
        return baseMapper.selectVoList(qw, UserInfoVo.class);
    }

    @Override
    public Page<UserInfoVo> customQueryPage(CustomQueryBo param, PageQuery pageQuery) {
        QueryWrapper<UserInfo> qw = this.buildCustomQuery(param);
        return baseMapper.selectVoPage(pageQuery.build(), qw, UserInfoVo.class);
    }

    private QueryWrapper<UserInfo> buildCustomQuery(CustomQueryBo param) {
        QueryWrapper<UserInfo> qw = Wrappers.query();
        qw.likeRight(StringUtils.isNotBlank(param.getArea()), "area", param.getArea());
        List<CustomQueryBo.QuerysDTO> querys = param.getQuerys();
        if (CollUtil.isNotEmpty(querys)) {
            querys.forEach(query -> {
                if (BusinessConstant.relation.AND.equals(query.getRelation())) {
                    switch (query.getCondition()) {
                        case BusinessConstant.condition.EQ: // 等于
                            qw.eq(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.CT: // 包含
                            qw.like(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.GT: // 大于
                            qw.gt(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.LT: // 小于
                            qw.lt(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.GE: // 大于等于
                            qw.ge(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.LE: // 小于等于
                            qw.le(query.getField(), query.getContent());
                            break;
                        default:
                            throw new RuntimeException("未知的查询条件");
                    }
                } else {
                    switch (query.getCondition()) {
                        case BusinessConstant.condition.EQ: // 等于
                            qw.or().eq(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.CT: // 包含
                            qw.or().like(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.GT: // 大于
                            qw.or().gt(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.LT: // 小于
                            qw.or().lt(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.GE: // 大于等于
                            qw.or().ge(query.getField(), query.getContent());
                            break;
                        case BusinessConstant.condition.LE: // 小于等于
                            qw.or().le(query.getField(), query.getContent());
                            break;
                        default:
                            throw new RuntimeException("未知的查询条件");
                    }
                }
            });
        }
        return qw;
    }
}
